# -*- encoding: utf-8 -*-
'''
@File    :   Utils.py   
@Contact :   desufnocs@163.com
@des     :   一些工具函数
 
@Modify Time       @Author      @Version    @Desciption
------------      ----------    --------    -----------
2025/2/17 12:31   AssenImpact      1.0         None
'''
import json
import logging
import os
import platform
import re
import socket
import string
import subprocess
from datetime import datetime, timedelta

import aiofiles
import qrcode
from passlib.context import CryptContext

from control import config as CONFIG


def device_base_info():
    '''
    获取设备基本信息
    '''
    host_name = socket.gethostname()
    system_name = platform.system()
    ip = socket.gethostbyname(socket.gethostname())
    return {
        "hostname": host_name,
        "systemname": system_name,
        "ip": ip
    }


def send_base_command(command: str | list[str]):
    '''
    运行简短的基本command命令
    '''
    try:
        subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                         shell=True)
        return True
    except:
        return False


def show_window_message(message: str):
    """
    window弹窗提示
    :param message:提示消息
    :return:
    """
    script = f'msg %username% 【来自程序Control】：{message}'
    send_base_command(script)


def modify_settings_file(key_name: str, new_value: str):
    """
    修改settings.txt文件内配置
    :param key_name: settings.txt配置名称
    :param new_value: 修改值
    :return:
    """
    with open(os.path.join(CONFIG.BASE_DIR, "settings.txt"), "r", encoding="utf-8") as fp:
        lines = fp.readlines()
    new_lines = []
    flag = True
    for line in lines:
        if key_name in line:
            new_lines.append(re.sub(key_name + r"=.*", f"{key_name}={new_value}", line))
            flag = False
        else:
            new_lines.append(line)
    if flag:
        new_lines.append(f"\n{key_name}={new_value}")
    with open(os.path.join(CONFIG.BASE_DIR, "settings.txt"), "w", encoding="utf-8") as file:
        file.writelines(new_lines)


async def create_script_file(filename, script_text):
    create_path = os.path.join(CONFIG.BASE_DIR, "script")
    if not os.path.exists(create_path):
        os.makedirs(create_path)
    create_path = os.path.join(create_path, filename)
    async with aiofiles.open(create_path, mode='w', encoding='utf-8') as sf:
        await sf.write(script_text)


def create_qrcode():
    """
    生成二维码
    :param data:
    :return:
    """
    base_info = device_base_info()
    qrcode_data = {
        "name": base_info["hostname"],
        "ip": base_info["ip"],
        "port": str(CONFIG.PORT),
        "custom_command": [],
        "key": get_key()
    }
    qr = qrcode.QRCode(
        version=1,  # 控制二维码的大小，1 是最小值
        error_correction=qrcode.constants.ERROR_CORRECT_L,  # 误差校正级别
        box_size=10,  # 每个小方块的像素大小
        border=4,  # 二维码边框宽度
    )

    qr.add_data(json.dumps(qrcode_data))  # 添加数据
    qr.make(fit=True)

    # 生成图片
    img = qr.make_image(fill="black", back_color="white")
    # 获取当前用户的桌面路径
    desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
    # 文件保存路径
    file_path = os.path.join(desktop_path, "扫一扫快速导入设备信息(配置后请删除).png")
    # 保存二维码图片
    img.save(file_path)
    img.show()  # 显示二维码
    # 下次运行时不再生成二维码
    modify_settings_file("CREATE_QRCODE", "0")


def create_key_file():
    """
    生成密钥文件
    :return:
    """
    desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
    file_path = os.path.join(desktop_path, "配置文件(首页左侧栏设备导入后请删除).txt")
    base_info = device_base_info()
    file_data = [{
        "name": base_info["hostname"],
        "ip": base_info["ip"],
        "port": str(CONFIG.PORT),
        "custom_command": [],
        "key": get_key()
    }]
    with open(file_path, "w", encoding="utf-8") as fp:
        fp.write(json.dumps(file_data))
    modify_settings_file("CREATE_TOKEN_FILE", "0")


def get_key():
    """
    获取加密密钥
    :return:
    """
    token_content = CryptContext(schemes=["bcrypt"], deprecated="auto")
    return token_content.hash(CONFIG.TOKEN_CIPHERTEXT)


def verify_token(request_token: str):
    """
    校验密钥
    :param request_token:
    :return:
    """
    token_content = CryptContext(schemes=["bcrypt"], deprecated="auto")
    return token_content.verify(CONFIG.TOKEN_CIPHERTEXT, request_token)


def save_log():
    """
    保存控制台日志
    :return:
    """
    log_dir = os.path.join(CONFIG.BASE_DIR, "logs")
    os.makedirs(log_dir, exist_ok=True)
    current_date = datetime.now().strftime("%Y-%m-%d")
    log_file = os.path.join(log_dir, f"{current_date}.log")
    threshold_date = datetime.now() - timedelta(days=CONFIG.LOG_KEEP)
    for filename in os.listdir(log_dir):
        file_path = os.path.join(log_dir, filename)
        try:
            file_date = datetime.strptime(filename.split(".")[0], "%Y-%m-%d")
            if file_date < threshold_date:
                os.remove(file_path)
        except ValueError:
            continue
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s - %(levelname)s - %(message)s",
        handlers=[
            logging.FileHandler(log_file, encoding="utf-8"),
        ],
    )
    return logging.getLogger("uvicorn")


def delete_script():
    """
    删除脚本文件
    """
    script_dir = os.path.join(CONFIG.BASE_DIR, "script")
    if not os.path.exists(script_dir):
        return
    for filename in os.listdir(script_dir):
        file_path = os.path.join(script_dir, filename)
        if os.path.isfile(file_path):
            try:
                # 删除文件
                os.remove(file_path)
            except Exception as e:
                print(f"脚本文件删除失败： {file_path}: {e}")


# def get_system_info():
#     return {
#         "主机名": socket.gethostname(),
#         "IP 地址": socket.gethostbyname(socket.gethostname()),
#         "系统": platform.system(),
#         "系统版本": platform.version(),
#         "架构": platform.architecture(),
#         "处理器": platform.processor(),
#         "CPU 核心数": psutil.cpu_count(logical=True),
#         "CPU 使用率": psutil.cpu_percent(interval=1),
#         "总内存": f"{psutil.virtual_memory().total / (1024 ** 3):.2f} GB",
#         "磁盘总空间": f"{psutil.disk_usage('/').total / (1024 ** 3):.2f} GB",
#     }
def get_path(path: str | None = None):
    if path:
        return os.listdir(path)
    else:
        return [f"{letter}:\\" for letter in string.ascii_uppercase if os.path.exists(f"{letter}:\\")]


if __name__ == '__main__':
    # print(send_base_command(["powershell", "-Command",
    #                          "& {(Add-Type '[DllImport(\"user32.dll\")] public static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);' -Name Win32SendMessage -Namespace Win32 -PassThru)::SendMessage(-1, 0x0112, 0xF170, 2)}"]))
    # print(send_base_command("msg %username% 【来自程序Control】"))

    # show_window_message("无配置文件，为了设备安全，请前往项目目录下settings.txt进行配置")

    # get_config()

    # create_qrcode()
    # token = get_key()
    # print(token)
    # print(verify_token(token))

    # modify_settings_file("CREATE_QRCODE", "1000")

    # print(get_system_info())

    print(get_path('F:\\'))
